package com.black.platform.organization.service.handler.impl;

import com.black.common.annotation.CacheRemove;
import com.black.common.auth.UserContextHolder;
import com.black.common.vo.OrganizationVo;
import com.black.platform.codeType.vo.CodeTypeVo;
import com.black.platform.organization.po.Organization;
import com.black.platform.organization.service.bz.OrganizationService;
import com.black.platform.organization.service.handler.OrganizationHandlerService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class OrganizationHandlerServiceImpl implements OrganizationHandlerService {

    private final OrganizationService organizationService;

    @Override
    public List<OrganizationVo> getOrganizationVoTreeByComCode(String comCode, String comName, boolean isIncludeInvalid) {
        List<Organization> organizationList = organizationService.getOrganizationsWithChildren(comCode, comName, isIncludeInvalid);
        return buildOrganizationTree(organizationList);
    }

    @Override
    public Organization getByComCode(String comCode) {
        return this.organizationService.getById(comCode);
    }

    @Override
    public boolean saveOrUpdate(Organization organization) {
        Organization dbOrganization = organizationService.getById(organization.getComCode());
        if (dbOrganization == null && !StringUtils.isEmpty(organization.getUpperCode())) {
            String subComCode = getSubComCode(organization.getUpperCode());
            organization.setComCode(subComCode);
        }
        return this.organizationService.saveOrUpdate(organization);
    }

    @Override
    @CacheRemove(value = "organization")
    public boolean delete(String comCode) {
        return this.organizationService.removeById(comCode);
    }

    @Override
    public List<CodeTypeVo> getOrganizationVoTree() {
        List<Organization> organizationList = organizationService.getOrganizationsWithChildren(UserContextHolder.getMainComCode(), null, false);
        return buildOrganizationSelectTree(organizationList);
    }

    @Override
    public String getSubComCode(String comCode) {
        String powerComCode = organizationService.getPowerComCode(comCode);
        String[] split = powerComCode.split(",");
        int index = split.length;
        if (!comCode.contains("_")) {
            comCode = comCode + "_";
        }
        if (index < 10) {
            return comCode + "0" + index;
        }
        return comCode + index;
    }

    @Override
    public Organization getMainOrganization() {
        return organizationService.getById(UserContextHolder.getMainComCode());
    }

    /***
     * 构建组织机构树
     * @param organizationList 组织机构集合
     * @return 组织机构树集
     */
    private List<OrganizationVo> buildOrganizationTree(List<Organization> organizationList) {
        List<OrganizationVo> voList = new ArrayList<>();
        Map<String, OrganizationVo> voMap = organizationList.stream().collect(Collectors.toMap(Organization::getComCode, organization -> {
            OrganizationVo organizationVo = new OrganizationVo();
            BeanUtils.copyProperties(organization, organizationVo);
            return organizationVo;
        }));
        for (Organization organization : organizationList) {
            if (StringUtils.isEmpty(organization.getUpperCode())) {
                voList.add(voMap.get(organization.getComCode()));
            } else {
                OrganizationVo organizationVo = voMap.get(organization.getUpperCode());
                if (organizationVo != null) {
                    if (organizationVo.getChildren() == null) {
                        voMap.get(organization.getUpperCode()).setChildren(new ArrayList<>());
                        voMap.get(organization.getUpperCode()).set_showChildren(true);
                    }
                    voMap.get(organization.getUpperCode()).getChildren().add(voMap.get(organization.getComCode()));
                } else {
                    voList.add(voMap.get(organization.getComCode()));
                }

            }
        }
        return voList;
    }

    /***
     * 构建组织机构树
     * @param organizationList 组织机构集合
     * @return 组织机构树集
     */
    private List<CodeTypeVo> buildOrganizationSelectTree(List<Organization> organizationList) {
        List<CodeTypeVo> voList = new ArrayList<>();
        Map<String, CodeTypeVo> voMap = organizationList.stream().collect(Collectors.toMap(Organization::getComCode, organization -> {
            CodeTypeVo organizationVo = new CodeTypeVo();
            organizationVo.setId(organization.getComCode());
            organizationVo.setLabel(organization.getComName());
            return organizationVo;
        }));
        for (Organization organization : organizationList) {
            if (StringUtils.isEmpty(organization.getUpperCode())) {
                voList.add(voMap.get(organization.getComCode()));
            } else {
                if (voMap.get(organization.getUpperCode()).getChildren() == null) {
                    voMap.get(organization.getUpperCode()).setChildren(new ArrayList<>());
                }
                voMap.get(organization.getUpperCode()).getChildren().add(voMap.get(organization.getComCode()));
            }
        }
        return voList;
    }

}
